#define _CRT_SECURE_NO_WARNINGS//这一句必须放在第一行
#include <graphics.h>		// 引用图形库头文件
#include <conio.h>
///*
//* * 15*15条边,(15条边中间14个格子+左留白0.5+右留白0.5),一共15个格子,一个格子像素为40
//* 则窗口的大小 15*40=600(x)  600(y)
//* //在第4,12线交界点需要画黑点
在第8线交界点需要画黑点
//* loadimage:用于从文件中读取图像。加载图片
//* putimage:显示图片
//* setlinecolor();
//* line:画线,需要两点坐标
//* setfillcolor:设置填充颜色
//* fillcircle:画填充(实心)圆,参数为坐标,半径
//* getmessage:获取鼠标消息
//* outtextxy:在指定位置(坐标)输出字符串
//* settextcolor:设置字体颜色
//* settextstyle:设置字体样式
//*
//*/
#define NUM 15
#define WIN_NUM 5//五子棋
 
int pieceArr[NUM][NUM] = { 0 };//记录15*15个棋盘的棋子情况,0表示没有棋子,1表示黑子,2表示白子
 
void Draw_line()
{
	setlinecolor(BLACK);
	//画竖线
	for (int x = 20; x < 600; x += 40)
		line(x, 20, x, 580);
	//画横线
	for (int y = 20; y < 600; y += 40)
		line(20, y, 580, y);
}
 
//画点
void Draw_point()
{
	setfillcolor(BLACK);
	fillcircle(140, 140, 5),
	fillcircle(140, 460, 5);
	fillcircle(460, 140, 5);
	fillcircle(460, 460, 5);
	fillcircle(300, 300, 5);
}
 
void Draw_piece(bool black, int x, int y)
{
	//计算棋盘中的坐标
	int i = x / 40;
	int j = y / 40;
 
	if (black)//黑子
	{
		setfillcolor(BLACK);
		pieceArr[i][j] = 1; //黑棋为1
	}
	else //白子
	{
		setfillcolor(WHITE);
		pieceArr[i][j] = 2; //白棋为2
	}
	fillcircle(20 + i * 40, 20 + j * 40, 15); //画一个圆（x,y,半径）
}
 
//判断这个位置是否有其他棋子
bool NicePos(int x, int y)
{
	//计算棋盘中的坐标
	int i = x / 40;
	int j = y / 40;
	return pieceArr[i][j] == 0;
}
 
//0:游戏继续,1:黑子赢; 2:白子赢
//只需要判断刚才下的棋子是否为5个即可
//判断行,列,45度和135度斜线
 
 
//判断游戏胜利
int GameOver(int x, int y)
{
	x = x / 40;//换算为下标
	y = y / 40;//换算为下标
	int n = pieceArr[x][y];//得到棋子颜色
	if (n == 0)
		return 0;
	int count = 0;//统计棋子的数量
	int i, j; //当前棋子的前面或后面，或上面或下面，或斜向上或斜向下
	
	//同行的棋子
	for (i = x; i >= 0 && pieceArr[i][y] == n; i--)//同行的前面有没有相同的
		count++;
	for (i = x + 1; i < NUM && pieceArr[i][y] == n; i++)//同行的后面有没有相同的
		count++;
	if (count >= WIN_NUM)
		return n;
 
	//同列的棋子
	count = 0;//重新计算
	for (j = y; j >= 0 && pieceArr[x][j] == n; j--)//同列的上面有没有相同的
		count++;
	for (j = y + 1; j < NUM && pieceArr[x][j] == n; j++)
		count++;
	if (count >= WIN_NUM)
		return n;
 
	//45度的棋子
	count = 0;//重新计算
	for (i = x, j = y; i < NUM && j >= 0 && pieceArr[i][j] == n; i++, j--)//右上
		count++;
	for (i = x - 1, j = y + 1; i >= 0 && j < NUM && pieceArr[i][j] == n; i--, j++)//左下
		count++;
	if (count >= WIN_NUM)
		return n;
 
	//135度的棋子
	count = 0;
	for (i = x, j = y; i >= 0 && j >= 0 && pieceArr[i][j] == n; i--, j--)//左上
		count++;
	for (i = x + 1, j = y + 1; i < NUM && j < NUM && pieceArr[i][j] == n; i++, j++)//右下
		count++;
	if (count >= WIN_NUM)
		return n;
 
	return 0;
}
 
int main()
{
	initgraph(600, 600);	// 创建绘图窗口，大小为 600x600 像素
 
	loadimage(NULL, _T("2.png")); //加载图片
 
	Draw_line();//画线
	
	Draw_point();//画点
 
	ExMessage m;//鼠标消息 ExMessage是一个结构体
	
	bool black = true;//黑子先下
 
	while (1)
	{
		m = getmessage(EX_MOUSE);
		if (m.message == WM_LBUTTONDOWN)
		{
			if (NicePos(m.x, m.y))
			{
				Draw_piece(black, m.x, m.y);
				int n = GameOver(m.x, m.y);
				if (n == 1)//黑子赢
				{
					settextcolor(RED);//字体颜色
					settextstyle(36, 0, _T("Consolas"));//字体样式
					outtextxy(250, 0, _T("黑棋赢了")); //输出文字内容
					break;
				}
				else if (n == 2)//白子赢
				{
					settextcolor(RED);
					settextstyle(36, 0, _T("Consolas"));
					outtextxy(250, 0, _T("白棋赢了"));
					break;
				}
				black = !black;
			}
		}
	}
	_getch();				// 按任意键继续
	closegraph();			// 关闭绘图窗口
	return 0;
}
 